home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX502 / SECT.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  24.9 KB  |  1,045 lines

  1. /* sect.c */
  2.  
  3. /* 
  4.  * Aug-23-88 jye. Change and add codes so that can be used for MS-DOS
  5.  * Dec-20-89 jye. Free a bug that HDX gives a error message when CD-ROM 
  6.  *                  is busy. 
  7.  * Feb-11-93 jye. changed the size of the 'sentdate' buff to 56 bytes 
  8.  *                  for the 'inquiry', this will fit some hard drives. (Ex.
  9.  *                  IBM OME 0663E15)
  10.  */
  11.  
  12. #include "obdefs.h"
  13. #include "osbind.h"
  14. #include "mydefs.h"
  15. #include "part.h"
  16. #include "hdx.h"
  17. #include "addr.h"
  18. #include "myerror.h"
  19.  
  20. #define    ZBUFSIZ    0x4000        /* about 16k == 32 sectors */
  21. #define    ZCOUNT    (ZBUFSIZ/0x200)    /* ZCOUNT = 32 */
  22. #define MAXUNITS 16            /* max number of logical units */
  23.  
  24. #define PUNINFO struct _punifno
  25. PUNINFO {
  26.         WORD puns;    /* number of physical units */
  27.         BYTE pun[MAXUNITS];
  28.         LONG partition_start[MAXUNITS]; /* offset to partition on */
  29.                                         /* physical unit */
  30. };
  31. extern long ostack;        /* old stack pointer */
  32. extern UWORD errcode();        /* function to return error code */
  33. extern int yesscan;        /* the flag for the func. IBMGPART use */
  34. extern long sptrk;        /* the sector per track */
  35. extern int npart;        /* the number of partitions */
  36. extern int ext;            /* the index of extended partition */
  37. extern int extend;        /* the index of end extended partition */
  38. extern int showmany;    /* the flag for show the too many device alert box */
  39. extern char ttscsi;        /* the flag for SCSI if set */
  40. extern char spscsixst;    /* set for the sparrow scsi exist */
  41. extern int needscan;    /* TRUE: if it is the first time to scan the units */
  42. extern int athead;        /* the # of data heads on the AT drive */
  43. extern int atcyl;        /* the # of cylinders on the AT drive */
  44. extern int atspt;        /* the # of sectors per track on the AT drive */
  45. extern int noacsi;        /* set for no ACSI drive in the system */
  46. extern char slwacsi;    /* 1: set for slow acsi device */
  47. extern char *drvid[];    /* for the id of the devices */
  48. /*
  49.  * Logical-to-dev+partition mapping table.
  50.  */
  51. int nlogdevs;                /* # logical devices */
  52. LOGMAP logmap[EXTRALOGD];    /* logical dev map */
  53. int livedevs[MAXPHYSDEVS];    /* live devs flags; 1: device is alive */
  54. int idevs[16];                /* the devs have id flags; 1: device has id */
  55. int typedev = 0x0000;        /* if set, driver is a removable driver */
  56. int typedrv = 0x0000;        /* if set, driver is a SCSI driver */
  57. int atexst;                    /* AT drive exists */
  58. int slvexst;                /* AT slave drive exists */
  59. char useblit;                /* set for it is not the stbook drive */
  60. int floptical=0;            /* set if it a floptical drive */
  61.  
  62.  
  63. /*
  64.  * Rebuild logical-to-physical mapping
  65.  * by reading and interpreting the root
  66.  * blocks for all physical devs.
  67.  *
  68.  */
  69.  
  70. rescan(flag, fnp)
  71.  
  72. int flag;    /* 0: don't report medium change error; */
  73.             /* non-0: report medium change error; */
  74. int fnp;    /* 0: do zero & markbad; 1: do format & ship; 2: do part */
  75.  
  76. {
  77.     int dev, scan=0;
  78.     char buf[512];
  79.     char sendata[56];
  80.     int partno, ret, inqret, i;
  81.     PART *partinfo;
  82.     char mask = 0x80;    /* 7th bit is set on */
  83.     int setmask;
  84.     int maxloop;
  85.  
  86.     noacsi = 1;                /* assume there is no ACSI in the system */
  87.     ostack = Super(NULL);    /* set supervice mode */
  88.  
  89.     ttscsi = chkscsi();        /* check if SCSI exists */
  90.     spscsixst = chksp();    /* check if sparrow scsi exists */
  91.     delay();
  92.     if ((atexst = chkide()))    { /* AT drive exist */
  93.         if (stbook())    {
  94.             useblit = 0;
  95.         } else {
  96.             useblit = chkblit();
  97.         }
  98.         if ((ret = identify(16, buf)) == OK)    {
  99.             delay();
  100.             /* in byte 54 of the buf having the drive's id */
  101.             gdrvid(16, &buf[54], drvid[16]);
  102.             /* return the number of cylinder, head, spt */
  103.             gparmfc(&atcyl, &athead, &atspt, buf);
  104.             /*
  105.             active(16);
  106.             */
  107.         } else { 
  108.             delay();
  109.             Super(ostack);
  110.             ret = errcode(16);
  111.             if (tsterr(ret) != OK) 
  112.                 return ERROR;
  113.             return (-3);    /* don't have to show the alert box */
  114.         }
  115.     }
  116.     delay();
  117.     /*    Now the hardware doesn't support the slave drive, so comment it out
  118.     if ((atexst) && (slvexst = slave()))    {  AT slave drive exist 
  119.         if ((ret = identify(17, buf)) == OK)    {
  120.             atscyl = getword(buf+2);
  121.             atshead = getword(buf+6);
  122.             atsspt = getword(buf+12);
  123.             delay();
  124.         } else { 
  125.             delay();
  126.             Super(ostack);
  127.             ret = errcode(17);
  128.             if (tsterr(ret) != OK) 
  129.                 return ERROR;
  130.             return (-3);    don't have to show the alert box
  131.         }
  132.     }
  133.     */
  134.     delay();
  135.     Super(ostack);
  136.     /* set the scent message box */
  137.     if ((needscan) && ((ttscsi)||(spscsixst)))
  138.         dsplymsg(scanmsg);
  139.  
  140.     /* disable all logical and physical devs */
  141.     for (dev = 0; dev < EXTRALOGD; ++dev)
  142.         logmap[dev].lm_physdev = -1;
  143.  
  144.     for (dev = 0; dev < MAXPHYSDEVS; ++dev)
  145.         livedevs[dev] = 0;
  146.  
  147.     /* set all devices have no id */
  148.     for(i=0; i < 16; i++)    {
  149.         idevs[i] = 0;
  150.     }
  151.  
  152.     /*
  153.      * Scan all physical devs
  154.      * and pick up partition structures.
  155.      */
  156.     nlogdevs = 0;
  157.     showmany = 0;
  158.     slwacsi = 0;
  159.     if (atexst)    {
  160.         maxloop = 18;
  161.         dev = 16;
  162.     } else if ((ttscsi)||(spscsixst))    {
  163.         if (spscsixst)    {
  164.             slwacsi = 1;
  165.         } 
  166.         maxloop = 16;
  167.         dev = 8;
  168.     } else {
  169.         maxloop = 8;
  170.         slwacsi = 1;
  171.         dev = 0;
  172.     }
  173. rerescan:
  174.     for (; dev < maxloop; ++dev)
  175.     {
  176.  
  177.         if (((dev == 16) && atexst) || ((dev == 17) && slvexst))    {
  178.             if ((ret = getroot(dev, buf, (SECTOR)0)) != 0)    {
  179.                 if (tsterr(ret) != OK)    
  180.                     err(rootread);
  181.                 slwacsi = 0;
  182.                 return(ERROR);
  183.             }
  184.             goto atst;    /* skip and do the at stuff only */
  185.         }
  186.         /* initialize the buffer */
  187.         for (i = 0; i < 56; i++)        {
  188.             sendata[i] = 0;
  189.         }
  190.  
  191.         /* check see the drive is a what kind of drive */
  192.            ostack = Super(NULL);
  193.            delay();
  194.         /*
  195.         if (spscsixst)    {
  196.             resetspscsi();
  197.         }
  198.         */
  199.         if ((inqret = inquiry(dev, (WORD)56, sendata)) != ERROR)    {
  200.             for (i=8; i < 56; i++)    {
  201.                 if (sendata[i])    {
  202.                     break;
  203.                 }
  204.             }
  205.             if (i < 56)    {    /* there are some date return */
  206.                 if ((sendata[8] == 'I') &&    (sendata[9] == 'N') &&
  207.                     (sendata[10] == 'S') &&    (sendata[11] == 'I') &&
  208.                     (sendata[12] == 'T') &&    (sendata[13] == 'E') &&
  209.                     (sendata[16] == 'I') &&    (sendata[17] == '3') &&
  210.                     (sendata[18] == '2') &&    (sendata[19] == '5'))    {
  211.                     /* it is a floptical INSITE I325 drive */
  212.                     floptical = 1;
  213.                 }
  214.                 gdrvid(dev, &sendata[8], drvid[dev]);
  215.                 idevs[dev] = 1;
  216.             }
  217.         }
  218.            delay();
  219.            Super(ostack);
  220.         setmask = 0x0001;
  221.         if (inqret & 0x08)    { /* the device is busy */
  222.             continue;
  223.         }
  224.         /* ret not equal OK, it may be a regular hard drive */
  225.         if ((inqret == OK)||(inqret == 7)) { /*it is not a regular hard drive*/
  226.             if (sendata[0])      {    /* it is not a hard drive */
  227.                 continue;
  228.             } else if (sendata[1] & mask)    { /* it is a removable drive */
  229.                 if (spscsixst)    {
  230.                       /* it is a SCSI drive */
  231.                     /* set the relative bit, 1 is a SCSI, other is not */
  232.                     typedrv |= setmask << dev;
  233.                     /* set the relative bit, 1 is a removable */
  234.                     typedev |= setmask << dev;
  235.                 } else {
  236.                     ;            /* don't set the SCSI bit */
  237.                 }
  238.             } else if (dev > 7)    {
  239.                   /* it is a SCSI drive */
  240.                 /* set the relative bit, 1 is a SCSI, other is not */
  241.                 typedrv |= setmask << dev;
  242.             }
  243.         }
  244.         if ((ret = getroot(dev, buf, (SECTOR)0)) < 0) {
  245.             if (!fnp)  rangelog(dev);
  246.             continue;
  247.         } else {        /* ret >= 0 */
  248.             if (ret > 0) {
  249.                 if ((flag) && (tsterr(ret) == OK))    {    
  250.                 /* if non-0, report error if medium changed */
  251.                         erasemsg();
  252.                         slwacsi = 0;
  253.                          return ERROR;
  254.                 }
  255.                 if ((ret = getroot(dev, buf, (SECTOR)0))) {    /* try again */
  256.                     if (ret > 0 && flag && tsterr(ret) == OK)    {
  257.                         erasemsg();
  258.                         slwacsi = 0;
  259.                         return ERROR;
  260.                     } else if ((ret > 0) && (!flag))    {
  261.                         if (((inqret == OK)||(inqret == 7)) && 
  262.                                              (sendata[1] & mask))    { 
  263.                             /* it is a removable drive */
  264.                             /* but forget insert the cartridge */
  265.                             err(instdrv);
  266.                             /*
  267.                             erasemsg();
  268.                             */
  269.                             /* set the relative bit, 1 is a removable */
  270.                             typedev |= setmask << dev;
  271.                         }
  272.                         /*
  273.                         if (fnp == 1)    {  do format 
  274.                             livedevs[dev] = 1;
  275.                             if (dev < 8)  there is a ACSI in the system 
  276.                                 noacsi = 0;
  277.                             yesscan = 1;
  278.                         }
  279.                         */
  280.                     }
  281.                     if (!fnp)    {
  282.                         rangelog(dev);
  283.                     }
  284.                     continue;
  285.                 }
  286.             }
  287.             if ((inqret == OK)||(inqret == 7))     {  /* it is a SCSI drive */
  288.                 if (sendata[1] & mask)    { /* it is a removable drive */
  289.                     /* set the relative bit, 1 is a removable, other is not */
  290.                     typedev |= setmask << dev;
  291.                 }
  292.             }
  293.     atst:
  294.             if (dev < 8)    {    /* there is a ACSI drive in the system */
  295.                 noacsi = 0;
  296.             }
  297.             livedevs[dev] = 1;
  298.             yesscan = 1;
  299.             if (stgpart(dev, buf, (PART *)&partinfo) == ERROR)    {
  300.                 erasemsg();
  301.                 slwacsi = 0;
  302.                 return ERROR;
  303.             }
  304.             if (ext != NO_EXT)    {
  305.                 sortpart(partinfo,SCAN_BS); 
  306.             }
  307.         for (partno = 0; partno < npart; ++partno) {
  308.             if ((partinfo[partno].p_flg & P_EXISTS) &&
  309.                 (partinfo[partno].p_siz != (SECTOR)0) &&
  310.                 (((partinfo[partno].p_id[0] == 'G') &&
  311.                  (partinfo[partno].p_id[1] == 'E') &&
  312.                  (partinfo[partno].p_id[2] == 'M'))   ||
  313.                  ((partinfo[partno].p_id[0] == 'B') &&
  314.                  (partinfo[partno].p_id[1] == 'G') &&
  315.                  (partinfo[partno].p_id[2] == 'M'))))   
  316.             {
  317.                 if (nlogdevs > EXTRALOGD)    {
  318.                     continue;
  319.                 }
  320.                 logmap[nlogdevs].lm_physdev = dev;
  321.                 logmap[nlogdevs].lm_partno = partno;
  322.                 logmap[nlogdevs].lm_start =  partinfo[partno].p_st;
  323.                 logmap[nlogdevs].lm_siz =      partinfo[partno].p_siz;
  324.                 ++nlogdevs;
  325.                 if (nlogdevs == MAXLOGDEVS)         {
  326.                     showmany = 1;
  327.                 }
  328.             }
  329.         }
  330.     }
  331.     inipart(partinfo, npart);
  332.     if (partinfo > 0)    Mfree(partinfo);
  333.     }
  334.  
  335.     if ((maxloop > 16) && ((ttscsi)||(spscsixst)))    {
  336.         maxloop = 16;
  337.         dev = 8;
  338.         slwacsi = 0;
  339.         if (spscsixst)    {
  340.             slwacsi = 1;
  341.         }
  342.         goto rerescan;
  343.     } else if (((maxloop > 16) && ((!ttscsi)&&(!spscsixst))) 
  344.                                || ((ttscsi)&&(maxloop>8)))    {
  345.         maxloop = 8;
  346.         dev = 0;
  347.         slwacsi = 1;
  348.         goto rerescan;
  349.     }
  350.     erasemsg();
  351.     slwacsi = 0;
  352.     return OK;
  353. }
  354.  
  355.  
  356.  
  357. /* get the indentification of drive */
  358.  
  359. gdrvid(indx, sptr, dptr)
  360. int indx;
  361. char *sptr;
  362. char *dptr;
  363. {
  364.  
  365.     int i, j=0;
  366.  
  367.     /* string in ptr is sperated by space */
  368.     for (i=0; i < 24; i++)    {
  369.         if ((*dptr++ = *sptr++) == 0x20)    {
  370.             j++;
  371.             if (j > 1)    {
  372.                 dptr--;
  373.             }
  374.         } else {
  375.             j = 0;
  376.         }
  377.     }
  378.     *(dptr-1) = 0;
  379.     /*
  380.     while ((*sptr != 0x20) && (*sptr))    {
  381.         *dptr++ = *sptr++;
  382.     }
  383.     *dptr++ = 0x20;
  384.     sptr = ptr+8;
  385.     while ((*sptr != 0x20) && (*sptr))    {
  386.         *dptr++ = *sptr++;
  387.     }
  388.     *dptr = 0;
  389.     */
  390. }
  391.  
  392.  
  393. /* rerange the partition informations. */
  394.  
  395.  sortpart(pinfo, type)
  396.  PART *pinfo;
  397.  int type;                /* USER_ED = 1: for user interface use */
  398.                          /* SCAN_BS = 0: for rescan() and laybs() use */
  399.  {
  400.      int i, j, k;
  401.     PART rpart[2];
  402.  
  403.     if (ext == NO_EXT) return OK;    /* don't need sort */
  404.     for (i = 0; i < 2; i++)    { /* initialize the temple space */
  405.         rpart[i].p_flg = 0L;
  406.         rpart[i].p_st = 0L;
  407.         rpart[i].p_siz = 0L;
  408.         for (k = 0; k < 3; k++)
  409.             rpart[i].p_id[k] = '0';
  410.     }
  411.     /* save the partitions that after the extened partitions */
  412.     for (i = ext+1, j=0; i < 4; i++, j++)        {
  413.         if (pinfo[i].p_flg & P_EXISTS)    {
  414.             rpart[j].p_flg = P_EXISTS;
  415.             rpart[j].p_st = pinfo[i].p_st;
  416.             rpart[j].p_siz = pinfo[i].p_siz;
  417.             for (k = 0; k < 3; k++)
  418.                 rpart[j].p_id[k] = pinfo[i].p_id[k];
  419.         } 
  420.     }
  421.     /* move the extened partition to the front */
  422.      for (i=4, j = ext; i < npart; i++, j++)    {
  423.         if (pinfo[i].p_flg & P_EXISTS)    {
  424.             pinfo[j].p_flg = P_EXISTS;
  425.             pinfo[j].p_st = (type)?(pinfo[i].p_st):(pinfo[i].p_st + ROOTSECT);
  426.             pinfo[j].p_siz = (type)?(pinfo[i].p_siz):(pinfo[i].p_siz-ROOTSECT);
  427.             for (k = 0; k < 3; k++)
  428.                 pinfo[j].p_id[k] = pinfo[i].p_id[k];
  429.         } else { j--;}    /* stay with that space */
  430.     }
  431.     /* copy the not extended partitions back after the extended partitions */
  432.      for (i=0; i < 2; i++, j++)    {
  433.         if (rpart[i].p_flg & P_EXISTS)    {
  434.             pinfo[j].p_flg = P_EXISTS;
  435.             pinfo[j].p_st = rpart[i].p_st;
  436.             pinfo[j].p_siz = rpart[i].p_siz;
  437.             for (k = 0; k < 3; k++)
  438.                 pinfo[j].p_id[k] = rpart[i].p_id[k];
  439.         } else {j--;}
  440.     }
  441.     for (i = j; i < npart; i++)    { /* set the rest to 0 */
  442.         pinfo[i].p_flg = 0L;
  443.         pinfo[i].p_st = 0L;
  444.         pinfo[i].p_siz = 0L;
  445.         for (k = 0; k < 3; k++)
  446.             pinfo[i].p_id[k] = '0';
  447.     }
  448. }
  449.  
  450.  
  451. /* 
  452.  * check to find out the exist of device
  453.  */
  454.  
  455. rangelog(dev)
  456.  
  457. int dev;
  458.  
  459. {
  460.     PUNINFO *divinfo;
  461.     int devnum;
  462.  
  463.     ostack = Super(NULL);
  464.     divinfo = ((PUNINFO *) *((long *)(0x516)));
  465.     for (devnum = 0; devnum < MAXUNITS; ++devnum)    {
  466.         if ((int)(divinfo->pun[devnum] & 0x07) == dev)    {
  467.             delay();
  468.             nlogdevs++;
  469.         }
  470.     }
  471.     Super(ostack);
  472. }
  473.  
  474. /*
  475.  * From a PHYSICAL device unit (0->7)
  476.  * and a partition number (0->3), figure
  477.  * out the LOGICAL disk number ('C'->'P').
  478.  *
  479.  * return the LOGICAL disk number or
  480.  * ERROR if the PHYSICAL device doesn't exist.
  481.  *
  482.  */
  483. phys2log(pdev, pno)
  484. int  pdev;    /* physical device unit */
  485. int  pno;    /* partition number (0 -> 3) */
  486. {
  487.     int logdev;        /* index to step through partitions of a phys unit */
  488.  
  489.     for (logdev = 0; logdev < EXTRALOGD; logdev++) {
  490.         if (logmap[logdev].lm_physdev == pdev &&
  491.             logmap[logdev].lm_partno == pno)
  492.             return ('C'+logdev);
  493.     }
  494.     return ERROR;
  495. }
  496.  
  497.  
  498. /*
  499.  * Map block on logical device to
  500.  * block on physical device;
  501.  * return ERROR if the logical device
  502.  * doesn't exist.
  503.  */
  504. log2phys(adev, ablk)
  505. int *adev;
  506. SECTOR *ablk;
  507. {
  508.     int dev;
  509.     char xbuf[256];
  510.     
  511.     dev = *adev;
  512.     if (dev >= 0 && dev <= 17)
  513.     return OK;
  514.  
  515.     dev = toupper(dev);
  516.     if (dev >= 'C' && dev <= 
  517.                 ('C'+EXTRALOGD)) /* from C to 't' are 50 logic device */
  518.     {
  519.     dev -= 'C';
  520.     *adev = logmap[dev].lm_physdev;
  521.     *ablk = logmap[dev].lm_start + *ablk;
  522.     return OK;
  523.     }
  524.  
  525.     return ERROR;
  526. }
  527.  
  528.  
  529.  
  530. /*
  531.  * Return physical starting block# of a partition
  532.  *
  533.  */
  534. SECTOR 
  535. logstart(ldev)
  536. int ldev;    /* logical device */
  537. {
  538.     ldev = toupper(ldev);
  539.     if (ldev >= 'C' && ldev <= 
  540.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  541.         ldev -= 'C';
  542.         return (logmap[ldev].lm_start);
  543.     }
  544.     return ERROR;
  545. }
  546.  
  547.  
  548.  
  549. /*
  550.  * Return physical starting block# of a partition's data block.
  551.  *
  552.  */
  553. SECTOR 
  554. logend(ldev)
  555. int ldev;    /* logical device */
  556. {
  557.     ldev = toupper(ldev);
  558.     if (ldev >= 'C' && ldev <= 
  559.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  560.         ldev -= 'C';
  561.         return (logmap[ldev].lm_start+logmap[ldev].lm_siz-1);
  562.     }
  563.     return ERROR;
  564. }
  565.  
  566.  
  567. #define    MFM 17        /* sectors per track for MFM */
  568. #define    RLL 26        /* sectors per track for RLL */
  569.  
  570.  
  571. /*
  572.  * Check if dev's root block is intact.
  573.  * Return number of sectors per track on disk.
  574.  *
  575.  */
  576. chkroot(dev, bs)
  577. int dev;
  578. char *bs;
  579. {
  580.     extern long get3bytes();
  581.     extern long get4bytes();
  582.     SETMODE *mb;
  583.     int i, ret, set, scsidrv, mask=0x0001;
  584.     int page=4, bsiz;
  585.     int head, spt;
  586.     SECTOR size, msiz, cyl;    /* size of media */
  587.     char buf[512], sendata[32];
  588.     long dmaptr, tmpptr;
  589.     char *dmahigh=0xffff8609,
  590.          *dmamid=0xffff860b,
  591.          *dmalow=0xffff860d;
  592.     
  593.     size = ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz;
  594.     
  595.     ret = OK;
  596.     if (dev == 16)    {        /* it is a IDE-AT drive */
  597.         msiz = (SECTOR)athead * (SECTOR)atcyl * (SECTOR)atspt;
  598.         if (size != msiz)
  599.             ret = ERROR;
  600.         return(ret);
  601.     } else if (dev > 7)    {    /* it is a scsi drive */
  602.         ostack = Super(NULL);
  603.         delay();
  604.         if ((ret = readcap(dev, 0, (long)0, sendata)) == OK) {
  605.             if (msiz = get4bytes(sendata))    {
  606.                 msiz += 1;
  607.                 delay();
  608.                 Super(ostack);
  609.                 goto chkend;
  610.             } 
  611.         } 
  612.         for (i = 0; i < 32; i++)
  613.             sendata[i] = 0;
  614.         if ((ret = mdsense(dev, 4, 0, 32, sendata)) == OK)    {
  615.             if((msiz=get3bytes(sendata+5)))    {
  616.                         delay();
  617.                         Super(ostack);
  618.                         goto chkend;
  619.             }
  620.         }
  621.         for (i = 0; i < 32; i++)
  622.             sendata[i] = 0;
  623.         if ((ret = mdsense(dev, 0, 0, 16, sendata)) == OK)    {
  624.             if((msiz=get3bytes(sendata+5)))    {
  625.                         delay();
  626.                         Super(ostack);
  627.                         goto chkend;
  628.             }
  629.         }
  630.         for (i = 0; i < 32; i++)
  631.             sendata[i] = 0;
  632.         if ((ret = mdsense(dev, 3, 0, 32, sendata)) == OK)    {
  633.             if((msiz=get3bytes(sendata+5)))    {
  634.                         delay();
  635.                         Super(ostack);
  636.                         goto chkend;
  637.             }
  638.         }
  639.         msiz = size;
  640.         delay();
  641.         Super(ostack);
  642.         goto chkerr;
  643.     }
  644.  
  645.     ostack = Super(NULL);
  646.     /* Get format parameters/ disk size from media */
  647.     set = typedev & (mask << dev);
  648.     scsidrv = typedrv & (mask << dev);
  649.     bsiz = ((set) || (scsidrv)) ? (16) : (22);
  650.     if ((set) || (scsidrv))    {
  651.         for (i = 0; i < 32; i++)
  652.             sendata[i] = 0;
  653.         mdsense(dev, 0, 0, bsiz, sendata);
  654.         if((msiz=get3bytes(sendata+5)))    {
  655.                     delay();
  656.                     Super(ostack);
  657.                     goto chkend;
  658.         }
  659. redopg:
  660.         for (i = 0; i < 32; i++)
  661.             sendata[i] = 0;
  662.         ret = mdsense(dev, page, 0, 32, sendata);/* use page code 4, but get */
  663.                                             /* info from the mdsense header */
  664.         for (i = 0; i < 32; i++)
  665.             if (sendata[i])
  666.                 break;
  667.         if ((i==32) && (page == 4))        {
  668.             page = 3;
  669.             goto redopg;
  670.         } else if (i == 32)    {
  671.             msiz = size;
  672.             delay();
  673.             Super(ostack);
  674.             goto chkend;
  675.         }
  676.         if (!(msiz = get3bytes(sendata+5)))    {
  677.             if (page == 4)    {
  678.                 page = 3;
  679.                 /*
  680.                 cyl = get3bytes(sendata+14);
  681.                 head = *(sendata+17);
  682.                 */
  683.                 goto redopg;
  684.             } else {
  685.                 /*
  686.                 spt = getword(sendata+22);
  687.                 msiz = cyl * head * spt;
  688.                 */
  689.                 msiz = size;
  690.             }
  691.         }
  692.         delay();
  693.         Super(ostack);
  694.         goto chkend;
  695.     } else    {
  696.         ret = mdsense(dev, 0, 0, 22, sendata);
  697.         delay();
  698.         Super(ostack);
  699.  
  700.         /* If full SCSI, will return number of blocks */
  701.         /* on disk at byte 5, 6 and 7.  If Adaptec,   */
  702.         /* will return 0 for number of blocks on disk */
  703.         /* on SCSI. */
  704.  
  705.             if (!(msiz = get3bytes(sendata+5))) {    /* no disk size returned? */
  706.             /* Yup, ie., it's adaptec's.  Interpret as SETMODE structure */
  707.             mb = (SETMODE *)sendata;
  708.             /* get number of cylinders */
  709.             cyl = mb->smd_cc[0];
  710.             cyl <<= 8;
  711.             cyl |= mb->smd_cc[1];
  712.     
  713.             /* get number of heads */
  714.             head = mb->smd_dhc;
  715.     
  716.             msiz = (SECTOR)head * (SECTOR)cyl * MFM;
  717.     
  718.             for (i = 0; i < 20; i++) {
  719.                 if ((ret = rdsects(dev, 1, buf, msiz+i)) == OK) {
  720.                     /* find out whether data has been transferred, by
  721.                           checking if dma pointer has been moved.      */
  722.  
  723.                     ostack = Super(NULL);
  724.                     delay();
  725.                     dmaptr = *dmahigh;
  726.                     dmaptr &= 0x0000003f;
  727.                     dmaptr <<= 16;
  728.                     tmpptr = *dmamid;
  729.                     tmpptr &= 0x000000ff;
  730.                     tmpptr <<= 8;
  731.                     dmaptr |= tmpptr;
  732.                     tmpptr = *dmalow;
  733.                     tmpptr &= 0x000000ff;
  734.                     dmaptr |= tmpptr;
  735.                     delay();
  736.                     Super(ostack);
  737.  
  738.                     if (dmaptr != buf)
  739.                         break;
  740.                    } else {            /* rdsects return an error */
  741.                     if (tsterr(ret) == OK) {
  742.                            break;
  743.                     }
  744.                 }
  745.             }
  746.     
  747.             if (ret == MDMCHGD)        /* check if error occurred */
  748.                 return (ret);
  749.        
  750.             /* Determine if media is MFM or RLL */
  751.             if (i < 20)    {
  752.                 msiz = (SECTOR)head * (SECTOR)cyl * RLL;
  753.             }
  754.             goto chkend;
  755.         }
  756.     }
  757. chkerr:
  758.     if (ret != 0) {
  759.         ret = errcode(dev);
  760.         if (tsterr(ret) != OK) 
  761.             return ERROR;
  762.         return (-3);    /* don't have to show the alert box */
  763.     }
  764. chkend:
  765.     if (size != msiz)
  766.         ret = ERROR;
  767.     else 
  768.         ret = OK;
  769.         
  770.     return (ret);
  771. }
  772.  
  773. /*
  774.  * Chkparm()
  775.  *    Check if given logical device has the asssumed parameters.
  776.  * Assumptions are:
  777.  *    - 512 bytes/sector
  778.  *    - 2 sectors/cluster
  779.  *    - 1 reserved sector
  780.  *    - 2 FATs
  781.  *
  782.  * Input:
  783.  *    ldev - logical device number ('C' -> 'P').
  784.  *
  785.  * Return:
  786.  *    OK - parameters of partition match the assumptions
  787.  *    ERROR - something went wrong.
  788.  *
  789.  * Comment:
  790.  *    Number of FATs is assumed to be 2.  Cannot check this 
  791.  * because previous version of HDX did not put that in the boot
  792.  * sector.
  793.  */
  794. chkparm(ldev)
  795. int ldev;
  796. {
  797.     char bs[512];        /* boot sector */
  798.     BOOT *boot;            /* boot structure */
  799.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  800.     int ret;
  801.  
  802.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  803.         if (tsterr(ret) != OK)
  804.             err(bootread);
  805.         ret = ERROR;
  806.         goto parmend;
  807.     }    
  808.  
  809.     boot = (BOOT *)bs;
  810.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  811.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  812.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  813.     if (bps % BPS            /* bytes per sector == ratio of 512 ? */
  814.     || res != 1) {            /* num sectors reserved == 1 ? */
  815.     ret = ERROR;            /* Nope, different from assumptions */
  816.     goto parmend;
  817.     }
  818.     
  819.     /* Check if sectors per cluster make sense */
  820.     if (boot->b_spc != 2) {
  821.         ret = ERROR;
  822.         goto parmend;
  823.     }
  824.     
  825.     ret = OK;                /* If yes, return OK */
  826.  
  827. parmend:
  828.     return ret;
  829. }
  830.  
  831.  
  832. ichkparm(ldev)
  833. int ldev;
  834. {
  835.     char bs[512];        /* boot sector */
  836.     BOOT *boot;            /* boot structure */
  837.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  838.     int ret;
  839.  
  840.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  841.         if (tsterr(ret) != OK)
  842.             err(bootread);
  843.         ret = ERROR;
  844.         goto parmend;
  845.     }    
  846.  
  847.     boot = (BOOT *)bs;
  848.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  849.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  850.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  851.     if (bps != 512            /* bytes per sector == 512 ? */
  852.     || res != 1) {            /* num sectors reserved == 1 ? */
  853.     ret = ERROR;            /* Nope, different from assumptions */
  854.     goto parmend;
  855.     }
  856.     
  857.     /* Check if sectors per cluster make sense */
  858.     if ((siz >= 0x8000L && boot->b_spc != 4) ||
  859.         (siz < 0x8000L && boot->b_spc != 2)) {
  860.         ret = ERROR;
  861.         goto parmend;
  862.     }
  863.     
  864.     ret = OK;                /* If yes, return OK */
  865.  
  866. parmend:
  867.     return ret;
  868. }
  869.  
  870.  
  871. /*
  872.  * Get dev's root block.
  873.  *
  874.  */
  875. getroot(dev, buf, sect)
  876. int dev;
  877. char *buf;
  878. SECTOR sect;
  879. {
  880.     return rdsects(dev, 1, buf, sect);
  881. }
  882.  
  883.  
  884. /*
  885.  * Put dev's root block.
  886.  *
  887.  */
  888. putroot(dev, buf, sect)
  889. int dev;
  890. char *buf;
  891. SECTOR sect;
  892. {
  893.     return wrsects(dev, 1, buf, sect);
  894. }
  895.  
  896.  
  897. /*
  898.  *  Read sector(s) from dev.
  899.  *
  900.  *  Input:
  901.  *    dev - device number (logical or physical).
  902.  *    num - number of sectors to read.
  903.  *    buf - buffer to write data read.
  904.  *    sect - starting sector number to read from.
  905.  *
  906.  *  Return:
  907.  *    errnum - 0: if read is successful.
  908.  *         an error code: if read is unsuccessful.
  909.  */
  910. rdsects(dev, num, buf, sect)
  911. int dev;            /* device number (logical or physical) */
  912. UWORD num;            /* number of sectors to read */
  913. char *buf;
  914. SECTOR sect;            /* starting sector to read from */
  915. {
  916.     int errnum;
  917.  
  918.     if (log2phys(&dev, §) < 0)
  919.     return ERROR;
  920.  
  921.     ostack = Super(NULL);
  922.     if (dev == 16)    { /* it is a AT drive */
  923.         /*
  924.         if (!(athead*atspt*sect))    {
  925.             formaterr(dev);
  926.             errnum = ERROR;
  927.         } else {
  928.             errnum = ideread(athead, atspt, sect, num, buf, (UWORD)dev);
  929.         }
  930.         */
  931.         errnum = ideread(athead, atspt, sect, num, buf, (UWORD)dev);
  932.     } else {
  933.         /*
  934.         if (spscsixst)    {
  935.             resetspscsi();
  936.         }
  937.         */
  938.         errnum = hread(sect, num, buf, (UWORD)dev);
  939.     }
  940.     /*
  941.     if (errnum == 04)    {      the drive is stop 
  942.         delay();
  943.         stunt();
  944.         delay();
  945.         errnum = hread(sect, num, buf, (UWORD)dev);
  946.     }
  947.     */
  948.     delay();
  949.     Super(ostack);
  950.  
  951.     if (errnum > 0) {
  952.         errnum = errcode(dev);
  953.     }
  954.         
  955.     return errnum;        /* return the error code */
  956. }
  957.  
  958.  
  959. /*
  960.  *  Write sector(s) to dev.
  961.  *
  962.  *  Input:
  963.  *    dev - device number (logical or physical).
  964.  *    num - number of sectors to write.
  965.  *    buf - buffer with data to be written.
  966.  *    sect - starting sector number to write to.
  967.  *
  968.  *  Return:
  969.  *    errnum - 0: if write is successful.
  970.  *         an error code: if write is unsuccessful.
  971.  */
  972. wrsects(dev, num, buf, sect)
  973. int dev;            /* device number (logical or physical */
  974. UWORD num;            /* number of sectors to write */
  975. char *buf;            /* buffer with data to be written */
  976. SECTOR sect;            /* starting sector to write to */
  977. {
  978.     int errnum;
  979.  
  980.     if (log2phys(&dev, §) < 0)
  981.     return ERROR;
  982.  
  983.     ostack = Super(NULL);
  984.     if (dev == 16)    { /* it is a AT drive */
  985.         /*
  986.         if (!(athead*atspt*sect))    {
  987.             formaterr(dev);
  988.             errnum = ERROR;
  989.         } else {
  990.             errnum = idewrite(athead, atspt, sect, num, buf, (UWORD)dev);
  991.         }
  992.         */
  993.         errnum = idewrite(athead, atspt, sect, num, buf, (UWORD)dev);
  994.     } else {
  995.         errnum = hwrite(sect, num, buf, (UWORD)dev);
  996.     }
  997.     delay();
  998.     Super(ostack);
  999.  
  1000.     if (errnum > 0) {
  1001.         errnum = errcode(dev);
  1002.     }
  1003.     return errnum;
  1004. }
  1005.  
  1006.  
  1007. /*
  1008.  * Zero range of sectors on dev.
  1009.  *
  1010.  */
  1011. zerosect(dev, start, count)
  1012. int dev;
  1013. SECTOR start;
  1014. UWORD count;
  1015. {
  1016.     char *zbuf;
  1017.     int  v;
  1018.     UWORD i;
  1019.  
  1020.     if ((zbuf = (char *)mymalloc(ZBUFSIZ)) <= 0)
  1021.         return err(nomemory);
  1022.         
  1023.     if (log2phys(&dev, &start) < 0) {
  1024.         free(zbuf);
  1025.     return ERROR;
  1026.     }
  1027.  
  1028.     fillbuf(zbuf, (long)ZBUFSIZ, 0L);
  1029.  
  1030.     while (count)
  1031.     {
  1032.         if (count > ZCOUNT)
  1033.             i = ZCOUNT;
  1034.         else i = count;
  1035.  
  1036.     if ((v = wrsects(dev, i, zbuf, start)) != 0)
  1037.         break;
  1038.     start += i;
  1039.     count -= i;
  1040.     }
  1041.     free(zbuf);
  1042.     
  1043.     return v;
  1044. }
  1045.